﻿#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <winsock2.h>
#define RECV_PORT 8000

void hand_error(const char *s)
{
    fprintf(stderr , "%s\n" , s);
    exit(1);
}

void send_status_code(SOCKET sock_cli , int status_code)
{
    send(sock_cli , (char*)&status_code , sizeof(status_code) , 0);
}
int file_extend(const char *file_name)
{
    int len = strlen(file_name);
    int idx = len - 1;
    while(idx > 0)
    {
        if(file_name[idx] == '.') break;
        idx -= 1;
    }
    if(len - idx == 3 && file_name[idx+1] == 't' && file_name[idx+2] == 'x' && file_name[idx+3] == 't')
        return 1;
    return 0;
}
void recv_file(SOCKET sock_cli , const char *file_name)
{
    FILE *fp;
    if(file_extend(file_name) == 0)
        fp = fopen(file_name, "wb");
    else
        fp = fopen(file_name , "r");
    if(fp == NULL)
        hand_error("open file error!");

    char buf[1024*1024];
    printf("......\n");
    int len , flag = 0;
    while( (len = recv(sock_cli , buf , 1024*1024 , 0)) && len > 0)
    {
        fwrite(buf , 1, len , fp);
    }


    fflush(fp);
    fclose(fp);
    printf("recv file success!\n");
}
void handle_request(SOCKET sock_cli)
{
    char file_name[125] , ch;
    int len , file_size;

    len = recv(sock_cli , file_name , 100 , 0);
    file_name[len] = 0;
    send_status_code(sock_cli , 200);
    recv(sock_cli , (char*)&file_size , sizeof(file_size) , 0);

    printf("name : %s\nsize : %d字节\n" , file_name , file_size);
    printf("是否接受这个文件？(y/n) :\n");

    scanf(" %c" , &ch);
    if(ch == 'n')
    {
        send_status_code(sock_cli , 100);
        return ;
    }
    send_status_code(sock_cli , 200);
    recv_file(sock_cli , file_name);
}
SOCKET create_socket()
{
    SOCKET sock_ser = socket(PF_INET , SOCK_STREAM , 0);
    if(sock_ser == INVALID_SOCKET)
        hand_error("socket filed!");

    SOCKADDR_IN addr_ser;
    addr_ser.sin_family = AF_INET;
    addr_ser.sin_port = htons(RECV_PORT);
    addr_ser.sin_addr.s_addr = htonl(INADDR_ANY);

    if((bind(sock_ser , (SOCKADDR*)&addr_ser , sizeof(addr_ser)) == SOCKET_ERROR))
        hand_error("bind filed!");
    if((listen(sock_ser , 10)) == SOCKET_ERROR)
        hand_error("listen filed!");

    return sock_ser;
}
int main()
{
    WSAData da;
    if(WSAStartup(MAKEWORD(2 , 2) , &da) != 0)
        hand_error("WsaStartup filed!");

    SOCKET sock_ser = create_socket();

    char ch;

    SOCKADDR_IN addr_cli;
    int len = sizeof(SOCKADDR) , flag = 1;
    printf("等待接受文件>-<\n");
    while(1)
    {
        if(flag != 1)
        {
            printf("\n\n等待接受文件^_^\n");
        }
        flag = 0;
        SOCKET sock_cli = accept(sock_ser , (SOCKADDR*)&addr_cli , &len);
        send(sock_cli , "Accept success!", strlen("Accept success!") , 0);
        handle_request(sock_cli);
        printf("是否还要继续接收文件？(y/n)\n");
        scanf(" %c" , &ch);
        if(ch == 'n')
            break;
    }
    printf("谢谢使用！\n");

    return 0;
}
